package common.jisc.command;

/**
 * User: Denis Fahritdinov
 * Date: 10/14/12
 * Time: 3:53 PM
 */
public class Command {

    protected static final int UNLIMITED_ARGUMENTS_NUMBER = -1;

    protected String command;
    protected String description;
    protected int argumentsNumber;
    protected CommandHandler handler;

    /**
     * @param command         user command
     * @param description     command description
     * @param argumentsNumber number of commands arguments
     * @param handler         command handler
     */
    public Command(String command, String description, int argumentsNumber, CommandHandler handler) {
        this.command = command;
        this.description = description;
        this.argumentsNumber = argumentsNumber;
        this.handler = handler;
    }

    /**
     * @param command     user command
     * @param description command description
     * @param handler     command handler
     */
    public Command(String command, String description, CommandHandler handler) {
        this(command, description, UNLIMITED_ARGUMENTS_NUMBER, handler);
    }

    /**
     *
     * @param command         user command
     * @param argumentsNumber number of commands arguments
     * @param handler         command handler
     */
    public Command(String command, int argumentsNumber, CommandHandler handler) {
        this(command, command, argumentsNumber, handler);
    }

    /**
     * @param command user command
     * @param handler command handler
     */
    public Command(String command, CommandHandler handler) {
        this(command, command, UNLIMITED_ARGUMENTS_NUMBER, handler);
    }

    /**
     * Can this command handle user command
     *
     * @param command         user command
     * @param argumentsNumber user command args
     * @return cat handle
     */
    public boolean canHandle(String command, int argumentsNumber) {
        boolean isCommandsEquals = this.command.equals(command);
        boolean isArgumentsUnlimited = this.argumentsNumber == UNLIMITED_ARGUMENTS_NUMBER;
        boolean isArgumentsEquals = isArgumentsUnlimited || this.argumentsNumber == argumentsNumber;
        return isCommandsEquals && isArgumentsEquals;
    }

    public String getCommand() {
        return command;
    }

    public String getDescription() {
        return description;
    }

    public int getArgumentsNumber() {
        return argumentsNumber;
    }

    public CommandHandler getHandler() {
        return handler;
    }

    public void setHandler(CommandHandler handler) {
        this.handler = handler;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Command command1 = (Command) o;

        if (argumentsNumber != command1.argumentsNumber) return false;
        if (command != null ? !command.equals(command1.command) : command1.command != null) return false;
        if (description != null ? !description.equals(command1.description) : command1.description != null)
            return false;
        if (handler != null ? !handler.equals(command1.handler) : command1.handler != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = command != null ? command.hashCode() : 0;
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + argumentsNumber;
        result = 31 * result + (handler != null ? handler.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        String args = argumentsNumber == UNLIMITED_ARGUMENTS_NUMBER ? "unlimited" : String.valueOf(argumentsNumber);
        return String.format("%s (with %s args)\t-\t%s", command, args, description);
    }
}
